package com.eh.excel;

import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by David Li on 2016/11/24.
 */
public class WritableExcelHandler<T> extends AbstractExcelHandler implements ExcelHandler {
    private Workbook workbook;
    private OutputStream os;

    @Override
    public void write(WritableExcelEvent excelEvent) {
        try {
            Map<ExcelTypeEnum, List<T>> dataMap = excelEvent.getDataMap();
            List<ExcelTypeEnum> excelTypeEnums = Lists.newArrayList(dataMap.keySet());
            if (CollectionUtils.isNotEmpty(excelTypeEnums)) {
                // 创建表工程
                String uploadPath = excelEvent.getUploadPath();
                File uploadFile = new File(uploadPath);
                if (!uploadFile.exists()) {
                    uploadFile.mkdir();
                }
                String tableName = MessageFormat
                        .format(PropertiesWriteUtil.getTableName(excelTypeEnums.get(0).getKey()), new SimpleDateFormat("yyyy.MM.dd").format(new Date()));
                String postfix = getPostfix(excelEvent.getExcelVersion());
                String filePath = uploadPath + tableName + postfix;
                File file = new File(filePath);
                if (file.exists()) {
                    file.renameTo(new File(uploadPath + tableName + "." + new SimpleDateFormat("HHmmss").format(new Date()) + postfix));
                }
                file.createNewFile();
                os = new FileOutputStream(filePath);
                // 创建Excel的工作书册 Workbook,对应到一个excel文档
                workbook = getWorkbook(excelEvent.getExcelVersion());

                for (int i = 0; i < excelTypeEnums.size(); i++) {
                    ExcelTypeEnum excelTypeEnum = excelTypeEnums.get(i);
                    String sheetName = PropertiesWriteUtil.getSheets(excelTypeEnum.getKey());
                    List<String> headers = PropertiesWriteUtil.getColumns(excelTypeEnum.getKey());
                    List<String> headerSigns = Lists.newArrayList();
                    List<String> headerNames = Lists.newArrayList();
                    List<Integer> columnWidths = Lists.newArrayList();
                    for (String header : headers) {
                        String[] t = header.split(":");
                        headerSigns.add(t[0]);
                        headerNames.add(t[1]);
                        columnWidths.add(Integer.parseInt(t[2]));
                    }
                    // 创建Sheet工程
                    Sheet sheet = workbook.createSheet(sheetName);

                    List<T> data = dataMap.get(excelTypeEnum);
                    // 写入表头
                    writeHeaders(sheet, headerNames, columnWidths);
                    // 写入数据
                    writeData(sheet, headerSigns, data);
                }
                workbook.write(os);
                return;
            }
            throw new RuntimeException("请传入数据！");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void writeHeaders(Sheet sheet, List<String> headerNames, List<Integer> columnWidths) {
        if (CollectionUtils.isNotEmpty(headerNames)) {
            Row row = sheet.createRow(0);
            for (int i = 0; i < headerNames.size(); i++) {
                sheet.setColumnWidth(i, columnWidths.get(i));
                String head = headerNames.get(i);
                Cell cell = row.createCell(i);
                cell.setCellValue(head);
                /** 设置背景颜色 */
                CellStyle style = workbook.createCellStyle();
                style.setFillForegroundColor(IndexedColors.GOLD.getIndex());
                style.setFillPattern(CellStyle.SOLID_FOREGROUND);
                style.setBorderBottom(CellStyle.BORDER_THIN);
                style.setBorderLeft(CellStyle.BORDER_THIN);
                style.setBorderRight(CellStyle.BORDER_THIN);
                style.setBorderTop(CellStyle.BORDER_THIN);
                /** 设置字体 */
                Font font = workbook.createFont();
                font.setFontName("微软雅黑");
                font.setFontHeightInPoints((short) 10);
                font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                style.setFont(font);
                /** 设置居中 */
                style.setAlignment(CellStyle.ALIGN_CENTER);
                cell.setCellStyle(style);
            }
        }
    }

    private void writeData(Sheet sheet, List<String> headerSigns, List<T> data) throws IllegalAccessException {
        if (CollectionUtils.isNotEmpty(data)) {
            for (int i = 0; i < data.size(); i++) {
                Row row = sheet.createRow(i + 1);
                T t = data.get(i);
                Field[] fields = t.getClass().getDeclaredFields();
                for (int j = 0; j < fields.length; j++) {
                    Field field = fields[j];
                    field.setAccessible(true);
                    if (headerSigns.contains(field.getName())) {
                        Cell cell = row.createCell(j);
                        cell.setCellValue(String.valueOf(field.get(t)));
                        CellStyle style = workbook.createCellStyle();
                        /** 设置边框 */
                        style.setBorderBottom(CellStyle.BORDER_THIN);
                        style.setBorderLeft(CellStyle.BORDER_THIN);
                        style.setBorderRight(CellStyle.BORDER_THIN);
                        style.setBorderTop(CellStyle.BORDER_THIN);
                        /** 设置字体 */
                        Font font = workbook.createFont();
                        font.setFontName("微软雅黑");
                        font.setFontHeightInPoints((short) 10);
                        style.setFont(font);
                        /** 设置自动换行 */
                        style.setWrapText(true);
                        style.setAlignment(CellStyle.ALIGN_RIGHT);
                        cell.setCellStyle(style);
                    }
                }
            }
        }
    }

}
